package io.ouka.jvm.hotspot.selfread.read;

import io.ouka.jvm.hotspot.selfread.InstanceKlass;
import io.ouka.jvm.hotspot.selfread.constant.FinalConstant;
import io.ouka.jvm.hotspot.selfread.domain.FieldInfo;
import io.ouka.jvm.hotspot.selfread.util.DataTranslate;

import java.util.ArrayList;
import java.util.List;

/**
 * @author ouka
 * FiledsReader
 */
public class FieldsReader extends AbstractReader {

    public FieldsReader() {
        this.iReader = new MethodInfoReader();
    }

    //fieldNums + field[]
    private int fieldNums;

    @Override
    public void preRead(byte[] content) {
        System.arraycopy(content, index, FinalConstant.U2BYTE, 0, FinalConstant.u2);
        fieldNums = DataTranslate.byteToUnsignedShort(FinalConstant.U2BYTE);
        index += FinalConstant.u2;
        byte[] bytes = new byte[content.length - index];
        System.arraycopy(content, index, bytes, 0, content.length - index);
        this.selfContent = bytes;
    }

    @Override
    public void read() {
        List<FieldInfo> fieldInfos = new ArrayList<>();
        int fieldBytesReadIndex = 0;
        FieldInfo fieldInfo = new FieldInfo();
        for (int i = 0; i < fieldNums; i++) {
            //access flag u2
            System.arraycopy(selfContent, fieldBytesReadIndex, FinalConstant.U2BYTE, 0, FinalConstant.u2);
            fieldBytesReadIndex += FinalConstant.u2;
            index += FinalConstant.u2;
            fieldInfo.setAccessFlag(DataTranslate.byteToUnsignedShort(FinalConstant.U2BYTE));
            //name index u2
            System.arraycopy(selfContent, fieldBytesReadIndex, FinalConstant.U2BYTE, 0, FinalConstant.u2);
            fieldBytesReadIndex += FinalConstant.u2;
            index += FinalConstant.u2;
            fieldInfo.setNameIndex(DataTranslate.byteToUnsignedShort(FinalConstant.U2BYTE));
            //descriptor index u2
            System.arraycopy(selfContent, fieldBytesReadIndex, FinalConstant.U2BYTE, 0, FinalConstant.u2);
            fieldBytesReadIndex += FinalConstant.u2;
            index += FinalConstant.u2;
            fieldInfo.setDescriptorIndex(DataTranslate.byteToUnsignedShort(FinalConstant.U2BYTE));
            //attributes_count u2
            System.arraycopy(selfContent, fieldBytesReadIndex, FinalConstant.U2BYTE, 0, FinalConstant.u2);
            fieldBytesReadIndex += FinalConstant.u2;
            index += FinalConstant.u2;
            fieldInfo.setAttributeCount(DataTranslate.byteToUnsignedShort(FinalConstant.U2BYTE));

            fieldInfos.add(fieldInfo);
        }
        instanceKlass.setInterfaceNums(fieldNums);
        instanceKlass.setFields(fieldInfos);
    }
}
